package com.jfirer.mvc.core.action;

import com.jfirer.baseutil.StringUtil;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.mvc.annotation.RequestMapping;
import com.jfirer.mvc.interceptor.ActionInterceptor;
import com.jfirer.mvc.resolver.ParamResolver;
import com.jfirer.mvc.viewrender.ViewRender;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 传统action类，用来代表一个事先定义的url地址响应，该url地址中不包含*这样的通配符
 */
public class Action
{
    /**
     * 调用该action的对象实例
     */
    private Object                         actionEntity;
    private ParamResolver[]                paramResolvers;
    // 该action响应的url地址
    private String                         requestUrl;
    private RequestMapping.RequestMethod[] requestMethods;
    private Method                         method;
    private String                         contentType;
    private ActionInterceptor[]            interceptors;
    private String                         token;
    private ViewRender                     viewRender;
    private String[]                       headerRules;
    private String                         name;

    public void render(HttpServletRequest request, HttpServletResponse response)
    {
        for (ActionInterceptor each : interceptors)
        {
            if (each.interceptor(request, response, this) == false)
            {
                return;
            }
        }
        try
        {
            if (contentType != null)
            {
                response.setContentType(contentType);
            }
            viewRender.render(request, response, method.invoke(actionEntity, resolveParams(request, response)));
        }
        catch (Throwable e)
        {
            ReflectUtil.throwException(e);
        }
    }

    private Object[] resolveParams(HttpServletRequest request, HttpServletResponse response)
    {
        int      length = paramResolvers.length;
        Object[] param  = new Object[length];
        for (int i = 0; i < length; i++)
        {
            try
            {
                param[i] = paramResolvers[i].resolve(request, response);
            }
            catch (Exception e)
            {
                throw new IllegalArgumentException(StringUtil.format("参数：{}绑定出现异常", paramResolvers[i].paramName()), e);
            }
        }
        return param;
    }

    public Object getActionEntity()
    {
        return actionEntity;
    }

    public void setActionEntity(Object actionEntity)
    {
        this.actionEntity = actionEntity;
    }

    public ParamResolver[] getParamResolvers()
    {
        return paramResolvers;
    }

    public void setParamResolvers(ParamResolver[] paramResolvers)
    {
        this.paramResolvers = paramResolvers;
    }

    public String getRequestUrl()
    {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl)
    {
        this.requestUrl = requestUrl;
    }

    public RequestMapping.RequestMethod[] getRequestMethods()
    {
        return requestMethods;
    }

    public void setRequestMethods(RequestMapping.RequestMethod[] requestMethods)
    {
        this.requestMethods = requestMethods;
    }

    public Method getMethod()
    {
        return method;
    }

    public void setMethod(Method method)
    {
        this.method = method;
    }

    public String getContentType()
    {
        return contentType;
    }

    public void setContentType(String contentType)
    {
        this.contentType = contentType;
    }

    public ActionInterceptor[] getInterceptors()
    {
        return interceptors;
    }

    public void setInterceptors(ActionInterceptor[] interceptors)
    {
        this.interceptors = interceptors;
    }

    public String getToken()
    {
        return token;
    }

    public void setToken(String token)
    {
        this.token = token;
    }

    public ViewRender getViewRender()
    {
        return viewRender;
    }

    public void setViewRender(ViewRender viewRender)
    {
        this.viewRender = viewRender;
    }

    public String[] getHeaderRules()
    {
        return headerRules;
    }

    public void setHeaderRules(String[] headerRules)
    {
        this.headerRules = headerRules;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }
}
